package com.hdc.walnut.common.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import org.apache.commons.lang3.StringUtils;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.springframework.util.ObjectUtils;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.*;

/*
 *
 * JSON工具类
 *
 */
public class JSONUtil {

    private static final Log log = LogFactory.getLog(JSONUtil.class);

    /*
     *  key的value值
     * */
    private static Object value;


    /*
     *  判断是否有子级
     * */
    private static boolean flag = true;

    /**
     * @param entry
     * @param key 指定的key值
     * @return
     * @描述 map按动态的key解析值 ，直到解析出想要的值
     * */
    public static Object parseJsonMap(Map.Entry<String, Object> entry, String key) {
        //log.info("value:" + value);
        if (ObjectUtils.isEmpty(value)) {
            //log.info("value is null");
            //log.info("key:" + key);
            if (flag) {
                //log.info("entry key:" + entry.getKey());
                //log.info("key:" + key);
                if (Objects.equals(entry.getKey(), key)) {
                    value = entry.getValue();
                    flag = false;
                } else {
                    //log.info("entry value:" + entry.getValue());
                    //如果是单个map继续遍历
                    if (entry.getValue() instanceof Map) {
                        //log.info("value is map");
                        if (isJsonMap(entry.getValue().toString())) {
                            LinkedHashMap<String, Object> jsonMap = JSON.parseObject(entry.getValue().toString(), new TypeReference<LinkedHashMap<String, Object>>() {
                            });
                            for (Map.Entry<String, Object> entry2 : jsonMap.entrySet()) {
                                if (!StringUtils.contains(entry2.getKey(), key)) {
                                    //log.info("entry2 entry2.getKey() is not key");
                                    value = parseJsonMap(entry2, key);
                                } else {
                                    //log.warn(" entry2 entry2.getKey() is key");
                                    value = entry2.getValue();
                                    //log.info("value:" + value);
                                    flag = false;
                                    break;
                                }
                            }
                        }
                    }

                    //如果是String就取它的值
                    if (entry.getValue() instanceof String) {
                        //log.info("entry.getValue() is String:");
                        //log.info("key" + entry.getKey() + ",  value:" + entry.getValue());
                        parseJsonString(entry.getValue().toString(), key);
                    }

                    //如果是空JSONArray,就返回它的值
                    if (entry.getValue() instanceof JSONArray && ((JSONArray) entry.getValue()).isEmpty()) {
                        //log.info("key" + entry.getKey() + ",  value: []");
                        value = "[]";
                        //log.info("value:" + value);
                        flag = false;
                    }

                    //如果是list就提取出来
                    if (entry.getValue() instanceof List && ((Collection) entry.getValue()).size() > 0) {
                        List list = (List) entry.getValue();
                        for (int i = 0; i < list.size(); i++) {
                            parseJsonString(list.get(i).toString(), key);
                        }
                    }
                }
            }
        }
        //log.info("value:" + value);
        return value;
    }

    /**
     * @param json
     * @param key 指定key值
     * @return
     * @描述 从JSON对象中，根据指定key获取值，只拿第一个
     * */
    public static Object parseJsonString(String json, Object key){
        //log.info("parseJsonString json:" + json);
        //log.info("parseJsonString key:" + key);
        if(!ObjectUtils.isEmpty(json) && !ObjectUtils.isEmpty(key)){
            //log.info(" parseJsonString json and key is not null");
            if(isJsonMap(json)){
                LinkedHashMap<String, Object> jsonMap = JSON.parseObject(json, new TypeReference<LinkedHashMap<String, Object>>() {
                });
                for(Map.Entry<String,Object> entry : jsonMap.entrySet()){
                    //log.info("entry key:" + entry.getKey());
                    //log.info("key" + key);
                    if(!StringUtils.contains(entry.getKey(),key.toString())){
                        //log.info("is not blank ");
                        value = parseJsonMap(entry, key.toString());
                    }else {
                        //log.warn(" is blank ");
                        value = entry.getValue();
                        break;
                    }
                }
            }
            return value;
        }else {
            //log.info("json and key is null");
            return null;
        }
    }

    /**
     * 判断字符串是否可以转化为json对象
     *
     * @param content
     * @return
     */
    public static boolean isJsonObject(String content) {
        // 此处应该注意，不要使用StringUtils.isEmpty(),因为当content为"  "空格字符串时，JSONObject.parseObject可以解析成功，
        // 实际上，这是没有什么意义的。所以content应该是非空白字符串且不为空，判断是否是JSON数组也是相同的情况。
        if (StringUtils.isBlank(content)) {
            return false;
        }
        try {
            JSONObject jsonStr = JSONObject.parseObject(content);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 判断字符串是否可以转化为JSON数组
     *
     * @param content
     * @return
     */
    public static boolean isJsonArray(String content) {
        if (StringUtils.isBlank(content)) {
            return false;
        }
        StringUtils.isEmpty(content);
        try {
            JSONArray jsonStr = JSONArray.parseArray(content);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 判断是否可以按照map动态的key解析值
     *
     * @param content
     * @return
     */
    public static boolean isJsonMap(String content) {
        //log.info("content:" + content);
        if (StringUtils.isBlank(content)) {
            return false;
        }
        StringUtils.isEmpty(content);
        try {
            LinkedHashMap<String, Object> jsonMap = JSON.parseObject(content, new TypeReference<LinkedHashMap<String, Object>>() {
            });
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 根据key获取value
     *
     * @param json 需要传入的JSON字符串
     * @param key  key的名称
     * @return value.toString() json字符串
     */
    public static String getJsonValueBykey(String json, Object key) {
        // 初始化
        value = "";
        //log.info("getJsonValueBykey json:" + json);
        //log.info("getJsonValueBykey key:" + key);
        // 判断[json] & [key]是否为空
        if (StringUtils.isNotBlank(json) && StringUtils.isNotBlank(key.toString())) {
            //log.info("getJsonValueBykey json and key is not null");
            // 判断[json]格式是否符合JSONArray
            if (isJsonArray(json)) {
                // 将[json]转为JSONArray并进行遍历匹配[key]对应的值
                //log.info("json is jsonArray");
                JSONArray jsonDataArray = JSONArray.parseArray(json);
                //log.info("jsonDataArray size:" + jsonDataArray.size());
                for (int i = 0; i < jsonDataArray.size(); i++) {
                    if (isJsonObject(jsonDataArray.get(i).toString())) {
                        //log.info("job json:" + jsonDataArray.get(i));
                        JSONObject job = jsonDataArray.getJSONObject(i);
                        value = parseJsonString(job.toJSONString(), key).toString();
                    }
                }
                //若无匹配项，则返回null
                if(value.equals("")){
                    return null;
                }
            } else if (isJsonObject(json)) {
                //log.warn("json is jsonObject");
                value = parseJsonString(json, key).toString();
            }
            return value.toString();
        } else {
            //log.error("json and key is null");
            return null;
        }
    }

    /**
     * 读取json文件（默认路径/resource/*）
     *
     * @return JSONString
     **/
    public static String ReadJson(String path) {
        BufferedReader br = null;
        try {
            br = new BufferedReader(new InputStreamReader(JSONUtil.class.getClassLoader().getResourceAsStream(path)));
            String line = br.readLine();
            StringBuilder sb = new StringBuilder();
            while (line != null) {
                sb.append(line + "\r\n");
                line = br.readLine();
            }
            return sb.toString();
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    public static String ReadJsonByCode(String json,String code){
        String jsonBody = getJsonValueBykey(json, code);
        //System.out.println("value:"+ jsonBody);
        return jsonBody;
    }

    /**
     * json 转 List<Map<String, Object>>
     * @Parma json
     *
     * @return JSONString
     **/
    public static ArrayList<Map<String, Object>> toArrayList(String data) throws UnsupportedEncodingException {
        /*
        // URL解码
        String dataSetStr= URLDecoder.decode(data, "utf-8");
        //System.out.println("[URL Decode]:"+dataSetStr);

        // 字符裁剪
        dataSetStr = dataSetStr.substring(dataSetStr.indexOf("=") + 1);
        if (dataSetStr.substring(0, 1).equals("{")  && dataSetStr.substring(dataSetStr.length() - 1).equals("}")) {
            dataSetStr = "[" + dataSetStr + "]";
        }
        //System.out.println("[CUTTING]:"+dataSetStr);
        if(getJsonValueBykey(dataSetStr,"dataSet")!=null){
            dataSetStr = getJsonValueBykey(dataSetStr,"dataSet");
        }
        //System.out.println("[CUTTING]:"+dataSetStr);
         */

        // String => JSONArray
        JSONArray dataSetArr= JSON.parseArray(data);
        //System.out.println("[dataSetArr]:"+dataSetArr);

        // JSONArray => ArrayList<Map<String,Object>>
        ArrayList<Map<String,Object>> dataSet=new ArrayList<Map<String,Object>>();
        for(int i=0;i<dataSetArr.size();i++){
            Map<String,Object> map = new HashMap<String, Object>();
            JSONObject jsObject= dataSetArr.getJSONObject(i); //访问JsonArray中的元素
            Iterator it =jsObject.entrySet().iterator(); //jsonObject 转 map
            while (it.hasNext()) {
                Map.Entry<String, Object> entry = (Map.Entry<String, Object>) it.next();
                map.put(entry.getKey(), entry.getValue());
            }
            dataSet.add(map);
        }
        return dataSet;
    }

    /**
     * 获取URL中的所有参数存进map
     * @Param request
     * @Param charset
     *
     * @return queryMap
     * */
    public static Map<String, Object> getQueryMap(HttpServletRequest request, String charset) throws IOException {
        Map<String, Object> queryMap = new HashMap<String, Object>();
        String queryString = request.getQueryString();
        String[] params = queryString.split("&");
        for (int i = 0; i < params.length; i++) {
            String[] kv = params[i].split("=");
            if (kv.length == 2) {
                String key = URLDecoder.decode(kv[0], charset);
                Object value = URLDecoder.decode(kv[1], charset);
                queryMap.put(key, value);
            } else if (kv.length == 1) {
                String key = URLDecoder.decode(kv[0], charset);
                queryMap.put(key, "");
            }
        }
        return queryMap;
    }

    /**
     * 获取URL参数 补充进titles中
     * @Param URLMap
     * @Param titles
     *
     * @Return titles
     * */
    public static String URLMatch(Map<String,Object> URLMap,String titles){
        // 遍历URLMap
        Iterator<Map.Entry<String, Object>> iter = URLMap.entrySet().iterator();
        while (iter.hasNext()) {
            Map.Entry entry = (Map.Entry) iter.next();
            String key = "{"+(String) entry.getKey()+"}";
            Object val = entry.getValue();
            //// 判断是何种占位符
            //// 获得子串在父串的位置 构思中
            //int L = key.length();
            //int n = titles.length();
            //for(int start = 0;start<n-L+1;start++){
            //    if(titles.substring(start,start+L).equals(key)){
            //        // 获取子串开始位置 start
            //
            //        // 根据key value 对字符串拼接
            //        StringBuffer sb = new StringBuffer(titles);
            //        sb.insert(start+L,val);
            //        titles = sb.toString();
            //    }
            //}
            // 通过占位符替换字符
            titles = titles.replace(key, val.toString());

        }
        //System.out.println(titles);
        return titles;
    }
}
